package jmine.tec.purge.service;

import jmine.tec.database.pack.PackException;
import jmine.tec.database.pack.services.PackEntityPersistenceHelper;
import jmine.tec.di.annotation.Injected;
import jmine.tec.purge.domain.PurgeConfig;
import jmine.tec.services.annotations.Execution;
import jmine.tec.services.annotations.Input;
import jmine.tec.services.annotations.ServiceImplementor;
import jmine.tec.services.api.ActionsEnum;
import jmine.tec.services.api.RawInput;
import jmine.tec.services.api.ServiceExecutionException;

/**
 * Serviço de inclusão de configuração de expurgo.
 * 
 * @author Marcio Ribeiro (mmr)
 * @created Aug 17, 2011
 */
@ServiceImplementor(action = ActionsEnum.INCLUIR)
public class PurgeConfigService {

    private static final String DATABASE_ID = "Database ID";

    private static final String NAME = "Name";

    private static final String DESCRIPTION = "Description";

    private static final String DAYS_TO_KEEP = "Days to Keep";

    private static final String MAX_WINDOW_SIZE = "Max Window Size";

    private static final String CRON_EXPRESSION = "Cron Expression";

    private static final String PURGER_BEAN_NAME = "Purger Bean Name";

    // Obrigatórios
    private String name;

    private Integer daysToKeep;

    private Integer maxWindowSize;

    // Opcionais
    private Long databaseId;

    private String description;

    private String cronExpression;

    // Injected
    private PackEntityPersistenceHelper helper;

    private RawInput rawInput;

    /**
     * Cria uma configuração de expurgo.
     * 
     * @throws ServiceExecutionException caso um erro inesperado ocorra.
     * @throws PackException caso falhe ao procurar por entidade.
     */
    @Execution
    public final void execute() throws ServiceExecutionException, PackException {
        PurgeConfig cfg = helper.findOrCreate(PurgeConfig.class, this.databaseId, this.name);

        cfg.setName(this.name);
        cfg.setDescription(this.description);
        cfg.setDaysToKeep(this.daysToKeep);
        cfg.setMaxWindowSize(this.maxWindowSize);
        cfg.setPurgerBeanName(rawInput.getRaw(PURGER_BEAN_NAME));
        cfg.setCronExpression(this.cronExpression);
        cfg.setEnabled(true);

        this.helper.save(cfg, this.databaseId);
    }

    /**
     * Define valor para campo name.
     * 
     * @param name valor para campo name.
     */
    @Input(fieldName = NAME)
    public void setName(String name) {
        this.name = name;
    }

    /**
     * Define valor para campo description.
     * 
     * @param description valor para campo description.
     */
    @Input(fieldName = DESCRIPTION, required = false)
    public void setDescription(String description) {
        this.description = description;
    }

    /**
     * Define valor para campo cronExpression.
     * 
     * @param cronExpression valor para campo cronExpression.
     */
    @Input(fieldName = CRON_EXPRESSION, required = false)
    public void setCronExpression(String cronExpression) {
        this.cronExpression = cronExpression;
    }

    /**
     * Define valor para campo daysToKeep.
     * 
     * @param daysToKeep valor para campo daysToKeep.
     */
    @Input(fieldName = DAYS_TO_KEEP)
    public void setDaysToKeep(Integer daysToKeep) {
        this.daysToKeep = daysToKeep;
    }

    /**
     * Define valor para campo maxWindowSize.
     * 
     * @param maxWindowSize valor para campo maxWindowSize.
     */
    @Input(fieldName = MAX_WINDOW_SIZE)
    public void setMaxWindowSize(Integer maxWindowSize) {
        this.maxWindowSize = maxWindowSize;
    }

    /**
     * Define valor para campo databaseId.
     * 
     * @param databaseId valor para campo databaseId.
     */
    @Input(fieldName = DATABASE_ID, required = false)
    public void setDatabaseId(Long databaseId) {
        this.databaseId = databaseId;
    }

    /**
     * Define valor para campo helper.
     * 
     * @param helper valor para campo helper.
     */
    @Injected
    public void setHelper(PackEntityPersistenceHelper helper) {
        this.helper = helper;
    }

    /**
     * @param rawInput raw input.
     */
    @Injected
    public void setRawInput(RawInput rawInput) {
        this.rawInput = rawInput;
    }
}
